package org.springblade.modules.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.modules.system.entity.Region;
import org.springblade.modules.system.excel.RegionExcel;
import org.springblade.modules.system.excel.RegionImporter;
import org.springblade.modules.system.service.IRegionService;
import org.springblade.modules.system.vo.RegionVO;
import org.springblade.modules.system.wrapper.RegionWrapper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 行政区划表 控制器
 *
 * @author Chill
 */
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_SYSTEM_NAME + "/region")
@Api(value = "行政区划表", tags = "行政区划表接口")
public class RegionController extends BladeController {

    private final IRegionService regionService;

    /**
     * 详情
     */
    @GetMapping("/detail")
    public R<RegionVO> detail(Region region) {
        Region detail = regionService.getOne(Condition.getQueryWrapper(region));
        return R.data(RegionWrapper.build().entityVO(detail));
    }

    /**
     * 分页 行政区划表
     */
    @GetMapping("/list")
    public R<IPage<Region>> list(Region region, Query query) {
        IPage<Region> pages = regionService.page(Condition.getPage(query), Condition.getQueryWrapper(region));
        return R.data(pages);
    }

    /**
     * 查询济南市所有区划
     */
    @GetMapping("/getAreaByJn")
    public R getAreaByJn(Region region) {
        LambdaQueryWrapper<Region> queryWrapper = new LambdaQueryWrapper();
        //code=3701济南市
        queryWrapper.and(wrapper -> wrapper.eq(Region::getParentCode, "3701"));
        List<Region> list = regionService.list(queryWrapper);
        return R.data(list);
    }

    /**
     * 查询市下的街道
     */
    @GetMapping("/getStreetByArea")
    public R getStreetByArea(Region region) {
        LambdaQueryWrapper<Region> queryWrapper = new LambdaQueryWrapper();
        //历下区所有的街道
        queryWrapper.and(wrapper -> wrapper.eq(Region::getParentCode, region.getCode()));
        List<Region> list = regionService.list(queryWrapper);
        return R.data(list);
    }

    /**
     * 懒加载列表
     */
    @GetMapping("/lazy-list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "区划编号", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "name", value = "区划名称", paramType = "query", dataType = "string")
    })
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "懒加载列表", notes = "传入menu")
    public R<List<RegionVO>> lazyList(String parentCode, @ApiIgnore @RequestParam Map<String, Object> menu) {
        List<RegionVO> list = regionService.lazyList(parentCode, menu);
        return R.data(RegionWrapper.build().listNodeLazyVO(list));
    }

    /**
     * 懒加载列表
     */
    @GetMapping("/lazy-tree")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "区划编号", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "name", value = "区划名称", paramType = "query", dataType = "string")
    })
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "懒加载列表", notes = "传入menu")
    public R<List<RegionVO>> lazyTree(String parentCode, @ApiIgnore @RequestParam Map<String, Object> menu) {
        List<RegionVO> list = regionService.lazyTree(parentCode, menu);
        return R.data(RegionWrapper.build().listNodeLazyVO(list));
    }

    /**
     * 新增 行政区划表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "新增", notes = "传入region")
    public R save(@RequestBody Region region) {
        return R.status(regionService.save(region));
    }

    /**
     * 修改 行政区划表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "修改", notes = "传入region")
    public R update(@RequestBody Region region) {
        return R.status(regionService.updateById(region));
    }

    /**
     * 新增或修改 行政区划表
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "新增或修改", notes = "传入region")
    public R submit(@RequestBody Region region) {
        return R.status(regionService.submit(region));
    }


    /**
     * 删除 行政区划表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "删除", notes = "传入主键")
    public R remove(@ApiParam(value = "主键", required = true) @RequestParam String id) {
        return R.status(regionService.removeRegion(id));
    }

    /**
     * 行政区划下拉数据源
     */
    @GetMapping("/select")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "下拉数据源", notes = "传入tenant")
    public R<List<Region>> select(@RequestParam(required = false, defaultValue = "00") String code) {
        List<Region> list = regionService.list(Wrappers.<Region>query().lambda().eq(Region::getParentCode, code));
        return R.data(list);
    }

    /**
     * 导入行政区划数据
     */
    @PostMapping("import-region")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "导入行政区划", notes = "传入excel")
    public R importRegion(MultipartFile file, Integer isCovered) {
        RegionImporter regionImporter = new RegionImporter(regionService, isCovered == 1);
        ExcelUtil.save(file, regionImporter, RegionExcel.class);
        return R.success("操作成功");
    }

    /**
     * 导出行政区划数据
     */
    @GetMapping("export-region")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "导出行政区划", notes = "传入user")
    public void exportRegion(@ApiIgnore @RequestParam Map<String, Object> region, HttpServletResponse response) {
        QueryWrapper<Region> queryWrapper = Condition.getQueryWrapper(region, Region.class);
        List<RegionExcel> list = regionService.exportRegion(queryWrapper);
        ExcelUtil.export(response, "行政区划数据" + DateUtil.time(), "行政区划数据表", list, RegionExcel.class);
    }

    /**
     * 导出模板
     */
    @GetMapping("export-template")
    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "导出模板")
    public void exportUser(HttpServletResponse response) {
        List<RegionExcel> list = new ArrayList<>();
        ExcelUtil.export(response, "行政区划模板", "行政区划表", list, RegionExcel.class);
    }

    @GetMapping("/regionJson")
    public R regionJson() {
        Map<String, Object> resultMap = new HashMap<>();
        //查询所有省的列表
        LambdaQueryWrapper<Region> provincequery = new LambdaQueryWrapper<>();
        provincequery.and(wrapper -> wrapper.eq(Region::getParentCode, "00"));
//        provincequery.and(wrapper -> wrapper.eq(Region::getCode, "37"));
        List<Region> provinceList = regionService.list(provincequery);

        Map<String, Object> provinceMap = new HashMap<>();
        for (Region pentity : provinceList) {
            provinceMap.put(pentity.getCode(), pentity.getName());
        }
        resultMap.put("provincesData", provinceMap);

//      ///根据省查询所有的市
        Map<String, Object> provinceCityMap = new HashMap<>();
        Map<String, Object> allCityAndAreaMap = new HashMap<>();
        for (Region pentity : provinceList) {
//            List<Region> cityList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, pentity.getCode()).eq(Region::getProvinceCode, "37"));
            List<Region> cityList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, pentity.getCode()));
            Map<String, Object> cityAllMap = new HashMap<>();
            for (Region city : cityList) {
                Map<String, Object> cityMap = new HashMap<>();
                cityMap.put("name", city.getName());
                cityMap.put("alpha", city.getAlpha());
                cityAllMap.put(city.getCode(), cityMap);
                ////一个市下边的所有区
//                List<Region> areaList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, city.getCode()).eq(Region::getProvinceCode, "37"));
                List<Region> areaList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, city.getCode()));
                Map<String, Object> cityAreaMap = new HashMap<>();
                Map<String, Object> areaAllMap = new HashMap<>();
                for (Region area : areaList) {
                    Map<String, Object> areaFullMap = new HashMap<>();
                    Map<String, Object> areaMap = new HashMap<>();
                    areaMap.put("name", area.getName());
                    areaMap.put("alpha", area.getAlpha());
                    areaFullMap.put(area.getCode(), areaMap);
                    areaAllMap.putAll(areaFullMap);
                }
                cityAreaMap.put(city.getCode(), areaAllMap);
//                System.out.println("=========AAAAAA=====" + JSON.toJSONString(cityAreaMap));
                allCityAndAreaMap.putAll(cityAreaMap);
            }
            provinceCityMap.put(pentity.getCode(), cityAllMap);
            provinceCityMap.putAll(allCityAndAreaMap);
        }
        resultMap.put("citiesData", provinceCityMap);
        return R.data(resultMap);
    }

    /////////////////////////获取所有的省/////////////////////
    @GetMapping("/getProvinces")
    public List<Region> getProvinces() {
        //查询所有省的列表
        LambdaQueryWrapper<Region> provincequery = new LambdaQueryWrapper<>();
        provincequery.and(wrapper -> wrapper.eq(Region::getParentCode, "00"));
        List<Region> provinceList = regionService.list(provincequery);
        return provinceList;
    }

    @GetMapping("/getCitysByProvinceCode")
    public List<Region> getCitysByProvinceCode(Region region) {
        List<Region> cityList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, region.getCode()));
        return cityList;
    }

    @GetMapping("/getAreasByCityCode")
    public List<Region> getAreasByCityCode(Region region) {
        List<Region> areaList = regionService.list(new LambdaQueryWrapper<Region>().eq(Region::getParentCode, region.getCode()));
        return areaList;
    }


}
